#!/bin/bash

# Copyright Redis Ltd. 2020 - present
# Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or
# the Server Side Public License v1 (SSPLv1).

# Settings
REDIS_SERVER_BINARY=${REDIS_SERVER_BINARY:-${PWD}/../../../redis/src/redis-server}
REDIS_CLI_BINARY=${REDIS_CLI_BINARY:-${PWD}/../../../redis/src/redis-cli}
REDISRAFT=${REDISRAFT:-${PWD}/../../redisraft.so}
HOST=${HOST:-127.0.0.1}
PORT=${PORT:-5000}
TIMEOUT=${TIMEOUT:-2000}
NODES=${NODES:-3}
LOGLEVEL=${LOGLEVEL:-notice}
SHARDING=${SHARDING:-yes}
ADDITIONAL_OPTIONS=${ADDITIONAL_OPTIONS:-}

# You may want to put the above config parameters into config.sh in order to
# override the defaults without modifying this script.

if [ -a config.sh ]
then
    source "config.sh"
fi

start_instance() {
    local port=$1

    echo "Starting $port"
    $REDIS_SERVER_BINARY \
        --port $port \
        --loglevel $LOGLEVEL \
        --logfile ${port}.log \
        --dbfilename dump-${port}.rdb \
        --daemonize yes \
        --loadmodule ${REDISRAFT} \
        --raft.log-filename raftlog-${port}.db \
        --raft.addr ${HOST}:${port} \
        --raft.sharding ${SHARDING} \
        ${ADDITIONAL_OPTIONS}
}

stop_instance() {
    local port=$1

    echo "Stopping $port"
    ${REDIS_CLI_BINARY} -p $port shutdown nosave
}

# Computed vars
ENDPORT=$((PORT+NODES))

if [ "$1" == "start" ]
then
    while [ $((PORT < ENDPORT)) != "0" ]; do
        PORT=$((PORT+1))
        start_instance $PORT
    done
    exit 0
fi

if [ "$1" == "create" ]
then
    PORT=$((PORT+1))
    ${REDIS_CLI_BINARY} -p $PORT raft.cluster init
    sleep 1

    p=$PORT
    while [ $((p < ENDPORT)) != "0" ]; do
        p=$((p+1))
        ${REDIS_CLI_BINARY} -p $p raft.cluster join ${HOST}:${PORT}
    done
    exit 0
fi

if [ "$1" == "stop" ]
then
    while [ $((PORT < ENDPORT)) != "0" ]; do
        PORT=$((PORT+1))
        stop_instance $PORT
    done
    exit 0
fi

if [ "$1" == "watch" ]
then
    if [ "$2" == "" ]; then
        INSTANCE=1
    else
        INSTANCE=$2
    fi

    PORT=$((PORT+INSTANCE))
    while [ 1 ]; do
        clear
        echo "`date` | $HOST:$PORT | INFO raft"
        ${REDIS_CLI_BINARY} -p $PORT info raft
        sleep 1
    done
    exit 0
fi

if [ "$1" == "tail" ]
then
    INSTANCE=$2
    PORT=$((PORT+INSTANCE))
    tail -f ${PORT}.log
    exit 0
fi

if [ "$1" == "tailall" ]
then
    tail -f *.log
    exit 0
fi

if [ "$1" == "call" ]
then
    shift
    while [ $((PORT < ENDPORT)) != "0" ]; do
        PORT=$((PORT+1))
        ${REDIS_CLI_BINARY} -p $PORT $@
    done
    exit 0
fi

if [ "$1" == "clean" ]
then
    rm -rf *.log
    rm -rf dump*.rdb
    rm -rf raftlog*
    exit 0
fi

if [ "$1" == "clean-logs" ]
then
    rm -rf *.log
    exit 0
fi

if [ "$1" == "call-instance" ]
then
    INSTANCE=$2
    shift 2
    PORT=$((PORT+INSTANCE))
    ${REDIS_CLI_BINARY} -p $PORT $@
    exit 0
fi

if [ "$1" == "stop-instance" ]
then
    INSTANCE=$2
    PORT=$((PORT+INSTANCE))
    stop_instance $PORT
    exit 0
fi

if [ "$1" == "start-instance" ]
then
    INSTANCE=$2
    PORT=$((PORT+INSTANCE))
    start_instance $PORT
    exit 0
fi

echo "Usage: $0 [start|create|stop|watch|tail|clean|call|call-instance|stop-instance|start-instance]"
echo "start                     -- Launch RedisRaft Redis instances."
echo "create                    -- Create a RedisRaft cluster."
echo "stop                      -- Stop RedisRaft instances."
echo "watch <id>                -- Show 'INFO raft' output first (default) or specified instance."
echo "tail <id>                 -- Run tail -f of instance at base port + ID."
echo "tailall                   -- Run tail -f for all the log files at once."
echo "clean                     -- Remove all instances data, logs, configs."
echo "clean-logs                -- Remove just instances logs."
echo "call <cmd>                -- Call a command on all instances."
echo "call-instance <id> <cmd>  -- Call a command on a specific instance."
echo "start-instance <id>       -- Start a RedisRaft instance that has been stopped."
echo "stop-instance <id>        -- Stop a RedisRaft instance."
